#ifndef __EKOS_USER_IPS_H__
#define __EKOS_USER_IPS_H__

typedef volatile struct ips_node_struct_t ips_node_t;

struct mutex_struct_t
{
	 spin_lock_t lock;
	 struct
	 {
		  unsigned int hold : 1;
		  unsigned int wait : 1;
		  unsigned int head : 20;
	 };
} __attribute__ ((aligned (4)));

typedef volatile struct mutex_struct_t mutex_t;

struct semaphore_struct_t
{
	 spin_lock_t lock;
	 uint32_t    count;
	 struct
	 {
		  unsigned int wait  : 1;
		  unsigned int head  : 20;
	 };
} __attribute__ ((aligned (4)));
typedef volatile struct semaphore_struct_t semaphore_t;

struct bqueue_struct_t
{
	 spin_lock_t lock;
	 struct
	 {
		  unsigned int wait  : 2;
		  unsigned int head  : 20;
	 };
} __attribute__ ((aligned (4)));
typedef volatile struct bqueue_struct_t bqueue_t;

int ips_init(void);

ips_node_t *ips_alloc(void);
void        ips_free(ips_node_t *node);

void mutex_init(mutex_t *mutex);
int  mutex_try_acquire(mutex_t *mutex);
void mutex_acquire(mutex_t *mutex, ips_node_t *node);
void mutex_ac_break(mutex_t *mutex, ips_node_t *node);
void mutex_release(mutex_t *mutex);

void semaphore_init(semaphore_t *sem, uint32_t count);
int  semaphore_try_acquire(semaphore_t *sem);
void semaphore_acquire(semaphore_t *sem, ips_node_t *node);
void semaphore_ac_break(semaphore_t *sem, ips_node_t *node);
int  semaphore_release(semaphore_t *sem);

void bqueue_init(bqueue_t *bq);
void bqueue_put(bqueue_t *bq, ips_node_t *node);
void bqueue_get(bqueue_t *bq, ips_node_t *node);

#endif
